package com.example.travel.controller;

import com.example.travel.bean.OrderBean;
import com.example.travel.service.OrderService;
import com.example.travel.service.RedisLockService;
import com.example.travel.utils.DateFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import java.util.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;

@Controller
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private RedisLockService redisLockService;

    @Value("${orders.lockExpireSeconds}")
    private int lockExpireSeconds;// 锁的过期时间，单位：秒

    /**
     * 景区门票下单
     */
    @RequestMapping(value = "/buySite", method = RequestMethod.POST)
    public ModelAndView buySite(@RequestParam Map<String, Object> params) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
        System.out.println(params.toString());
        try {
            if(params.get("userName") == null || params.get("siteID") == null || params.get("num") == null || params.get("startDate") == null) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "参数错误");
                return modelAndView;
            }
            String userName = params.get("userName").toString();
            int siteID = Integer.parseInt(params.get("siteID").toString());
            int num = Integer.parseInt(params.get("num").toString());
            String startDate = params.get("startDate").toString();

            String lockValue = UUID.randomUUID().toString();// 生成唯一标识，用于释放锁时的验证
            String lockKey = "order:lock:" + userName;// 锁的key
            boolean isLocked = false;
            try {
                // 尝试获取锁
                isLocked = redisLockService.tryLock(lockKey, lockValue, lockExpireSeconds);
                if (!isLocked) {
                    // 获取锁失败，说明用户正在下单中
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "操作过于频繁，请稍后再试");
                    return modelAndView;
                }
                int result = orderService.buySite(userName, siteID, num, startDate);
                System.out.println(result);
                if (result > 0) {
                    modelAndView.addObject("status", "success");
                    modelAndView.addObject("message", "景区门票预订成功，请凭订单凭证（编号）消费！");
                } else {
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "景区门票预订失败");
                }
            } catch (Exception e) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "订单处理错误: " + e.getMessage());
            } finally {
                if (isLocked) {
                    // 释放锁（确保只有加锁的线程才能释放锁）
                    redisLockService.unlock(lockKey, lockValue);
                }
            }

        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("message", "系统错误: " + e.getMessage());
        }

        return modelAndView;
    }

    /**
     * 民俗下单
     */
    @RequestMapping(value = "/buyHotel", method = RequestMethod.POST)
    public ModelAndView buyHotel(@RequestParam Map<String, Object> params) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
        try {
            if(params.get("userName") == null || params.get("hotelID") == null || params.get("num") == null || params.get("startDate") == null ||params.get("endDate") == null) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "参数错误");
                return modelAndView;
            }
            String userName = params.get("userName").toString();
            int hotelID = Integer.parseInt(params.get("hotelID").toString());
            int num = Integer.parseInt(params.get("num").toString());
            String startDate = params.get("startDate").toString();
            String endDate = params.get("endDate").toString();

            String lockValue = UUID.randomUUID().toString();// 生成唯一标识，用于释放锁时的验证
            String lockKey = "order:lock:" + userName;// 锁的key
            boolean isLocked = false;
            try {
                // 尝试获取锁
                isLocked = redisLockService.tryLock(lockKey, lockValue, lockExpireSeconds);
                if (!isLocked) {
                    // 获取锁失败，说明用户正在下单中
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "操作过于频繁，请稍后再试");
                    return modelAndView;
                }
                int result = orderService.buyHotel(userName, hotelID, num, startDate, endDate);
                System.out.println(result);
                if (result != 0) {
                    if(result == -4 || result == -5) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "余量不足！");
                    } else if (result == -3) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "该民宿不存在！");
                    } else if (result == -2) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "可能存在并发操作，请重试！");
                    } else if (result == -1) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "下单出错！");
                    } else{
                        modelAndView.addObject("status", "success");
                        modelAndView.addObject("message", "民宿预订成功，请凭订单凭证（编号）消费！");
                    }
                } else {
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "民宿预订失败");
                }
            } catch (Exception e) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "订单处理错误: " + e.getMessage());
            } finally {
                if (isLocked) {
                    // 释放锁（确保只有加锁的线程才能释放锁）
                    redisLockService.unlock(lockKey, lockValue);
                }
            }
        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("message", "系统错误: " + e.getMessage());
        }

        return modelAndView;
    }

    /**
     * 美食下单
     */
    @RequestMapping(value = "/buyProduct", method = RequestMethod.POST)
    public ModelAndView buyProduct(@RequestParam Map<String, Object> params) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());

        try {
            if(params.get("userName") == null || params.get("productID") == null || params.get("num") == null || params.get("startDate") == null) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "参数错误");
                return modelAndView;
            }
            String userName = params.get("userName").toString();
            int productID = Integer.parseInt(params.get("productID").toString());
            int num = Integer.parseInt(params.get("num").toString());
            String startDate = params.get("startDate").toString();

            String lockValue = UUID.randomUUID().toString();// 生成唯一标识，用于释放锁时的验证
            String lockKey = "order:lock:" + userName;// 锁的key
            boolean isLocked = false;
            try {
                // 尝试获取锁
                isLocked = redisLockService.tryLock(lockKey, lockValue, lockExpireSeconds);
                if (!isLocked) {
                    // 获取锁失败，说明用户正在下单中
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "操作过于频繁，请稍后再试");
                    return modelAndView;
                }

                int result = orderService.buyProduct(userName, productID, num, startDate);
                System.out.println(result);
                if (result != 0) {
                    if(result == -4 || result == -5) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "余量不足！");
                    } else if (result == -3) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "该美食不存在！");
                    } else if (result == -2) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "可能存在并发操作，请重试！");
                    } else if (result == -1) {
                        modelAndView.addObject("status", "error");
                        modelAndView.addObject("message", "预定出错！");
                    } else{
                        modelAndView.addObject("status", "success");
                        modelAndView.addObject("message", "美食预订成功，请凭订单凭证（编号）消费！");
                    }
                } else {
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "美食预订失败");
                }
            } catch (Exception e) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "订单处理错误: " + e.getMessage());
            } finally {
                if (isLocked) {
                    // 释放锁（确保只有加锁的线程才能释放锁）
                    redisLockService.unlock(lockKey, lockValue);
                }
            }
        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("message", "系统错误: " + e.getMessage());
        }

        return modelAndView;
    }

    /**
     * 人文活动下单
     */
    @RequestMapping(value = "/buyActivity", method = RequestMethod.POST)
    public ModelAndView buyActivity(@RequestParam Map<String, Object> params) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());

        try {
            if(params.get("userName") == null || params.get("activityID") == null || params.get("num") == null || params.get("startDate") == null) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "参数错误");
                return modelAndView;
            }
            String userName = params.get("userName").toString();
            int activityID = Integer.parseInt(params.get("activityID").toString());
            int num = Integer.parseInt(params.get("num").toString());
            String startDate = params.get("startDate").toString();

            String lockValue = UUID.randomUUID().toString();// 生成唯一标识，用于释放锁时的验证
            String lockKey = "order:lock:" + userName;// 锁的key
            boolean isLocked = false;
            try {
                // 尝试获取锁
                isLocked = redisLockService.tryLock(lockKey, lockValue, lockExpireSeconds);
                if (!isLocked) {
                    // 获取锁失败，说明用户正在下单中
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "操作过于频繁，请稍后再试");
                    return modelAndView;
                }

                int result = orderService.buyActivity(userName, activityID, num, startDate);
                System.out.println(result);
                if (result != 0) {
                    modelAndView.addObject("status", "success");
                    modelAndView.addObject("message", "人文活动预订成功，请凭订单凭证（编号）消费！");
                } else {
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "人文活动预订失败");
                }
            } catch (Exception e) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "订单处理错误: " + e.getMessage());
            } finally {
                if (isLocked) {
                    // 释放锁（确保只有加锁的线程才能释放锁）
                    redisLockService.unlock(lockKey, lockValue);
                }
            }
        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("message", "系统错误: " + e.getMessage());
        }
        return modelAndView;
    }

    /**
     * 旅游线路下单
     */
    @RequestMapping(value = "/buyLine", method = RequestMethod.POST)
    public ModelAndView buyLine(@RequestParam Map<String, Object> params) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
        try {
            if(params.get("userName") == null || params.get("lineID") == null || params.get("num") == null || params.get("startDate") == null) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "参数错误");
                return modelAndView;
            }
            String userName = params.get("userName").toString();
            int lineID = Integer.parseInt(params.get("lineID").toString());
            int num = Integer.parseInt(params.get("num").toString());
            String startDate = params.get("startDate").toString();

            String lockValue = UUID.randomUUID().toString();// 生成唯一标识，用于释放锁时的验证
            String lockKey = "order:lock:" + userName;// 锁的key
            boolean isLocked = false;
            try {
                // 尝试获取锁
                isLocked = redisLockService.tryLock(lockKey, lockValue, lockExpireSeconds);
                if (!isLocked) {
                    // 获取锁失败，说明用户正在下单中
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "操作过于频繁，请稍后再试");
                    return modelAndView;
                }

                int result = orderService.buyLine(userName, lineID, num, startDate);
                System.out.println(result);
                if (result > 0) {
                    modelAndView.addObject("status", "success");
                    modelAndView.addObject("message", "旅游线路预订成功，请凭订单凭证（编号）消费！");
                } else {
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "旅游线路预订失败");
                }
            } catch (Exception e) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "订单处理错误: " + e.getMessage());
            } finally {
                if (isLocked) {
                    // 释放锁（确保只有加锁的线程才能释放锁）
                    redisLockService.unlock(lockKey, lockValue);
                }
            }
        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("message", "系统错误: " + e.getMessage());
        }

        return modelAndView;
    }

    /**
     * 根据用户名查询订单列表
     */
    @RequestMapping(value = "/getOrderList", method = RequestMethod.GET)
    public ModelAndView getOrderList(@RequestParam("userName") String userName,@RequestParam("page") int page,@RequestParam("pageSize") int pageSize) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
        try {
            int offset = (page - 1) * pageSize;
            List<OrderBean> orderList = orderService.getOrderList(userName,offset,pageSize);
            modelAndView.addObject("status", "success");
            modelAndView.addObject("dataList", orderList);
        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("dataList", new ArrayList<>());
        }

        return modelAndView;
    }

    /**
     * 获取最近的订单信息（用于管理员后台）
     */
    @RequestMapping(value = "/getRecentOrders", method = RequestMethod.GET)
    public ModelAndView getRecentOrders(@RequestParam(defaultValue = "10") int limit) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
        try {
            List<OrderBean> recentOrders = orderService.getRecentOrders(limit);
            modelAndView.addObject("status", "success");
            modelAndView.addObject("dataList", recentOrders);
            modelAndView.addObject("message", "获取最近订单成功");
        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("dataList", new ArrayList<>());
            modelAndView.addObject("message", "获取最近订单失败: " + e.getMessage());
        }
        return modelAndView;
    }

    /**
     * 退订
     */
    @RequestMapping(value = "/refundOrder", method = RequestMethod.POST)
    public ModelAndView refundOrder(@RequestParam Map<String, Object> params) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
        try {
            if(params.get("orderID") == null || params.get("userName") == null || params.get("orderCode") == null){
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "参数错误");
            }
            int orderID = Integer.parseInt(params.get("orderID").toString());
            String userName = params.get("userName").toString();
            String orderCode = params.get("orderCode").toString();

            String lockValue = UUID.randomUUID().toString();// 生成唯一标识，用于释放锁时的验证
            String lockKey = "refundOrder:lock:" + userName;// 锁的key
            boolean isLocked = false;
            try {
                // 尝试获取退订锁
                isLocked = redisLockService.tryLock(lockKey, lockValue, lockExpireSeconds);
                if (!isLocked) {
                    // 获取锁失败，说明用户正在下单中
                    modelAndView.addObject("status", "error");
                    modelAndView.addObject("message", "退订操作过于频繁，请稍后再试");
                    return modelAndView;
                }

                String result = orderService.refundOrder(orderID,userName,orderCode);
                System.out.println(result);
                if (result.contains("退订成功")) {
                    modelAndView.addObject("status", "success");
                } else {
                    modelAndView.addObject("status", "error");
                }
                modelAndView.addObject("message", result);
            } catch (Exception e) {
                modelAndView.addObject("status", "error");
                modelAndView.addObject("message", "退订处理错误: " + e.getMessage());
            } finally {
                if (isLocked) {
                    // 释放锁（确保只有加锁的线程才能释放锁）
                    redisLockService.unlock(lockKey, lockValue);
                }
            }

        } catch (Exception e) {
            modelAndView.addObject("status", "error");
            modelAndView.addObject("message", "系统错误: " + e.getMessage());
        }

        return modelAndView;
    }
}
